#include "gtest/gtest.h"

#include "BreakPointService.h"
#include "BreakPointState.h"

TEST(BreakPointServiceStatusTest, startAndStop){

    BreakPointService service;
    ASSERT_TRUE(service.getState().isEnd());

    service.start();
    ASSERT_TRUE(service.getState().isInited());

    service.connected();
    ASSERT_TRUE(service.getState().isConnected());

    service.receivedLoginResp("login-rsp");
    ASSERT_TRUE(service.getState().isLogined());

    service.timeout();
    service.receivedBreakPointResp("breakpoint-rsp");

    service.receivedNormalResp("normal");

    service.disconnected();
    ASSERT_TRUE(service.getState().isDisconnected());

    service.stop();
    ASSERT_TRUE(service.getState().isEnd());
}

TEST(BreakPointServiceStatusTest, errorUse){
    BreakPointService service;
    service.start();
    ASSERT_TRUE(service.getState().isInited());


    ASSERT_EQ(-1, service.disconnected()); // switch status, check failed 
    ASSERT_TRUE(service.getState().isInited());

    ASSERT_EQ(0, service.connected()); //switch OK 
    ASSERT_TRUE(service.getState().isConnected());

    service.stop();
    ASSERT_TRUE(service.getState().isEnd());
}



#include "BreakPointState.h"

TEST(BreakPointStatusTest, use){
    IBreakPointState * state = new BreakPointState;
    ASSERT_TRUE(state->isEnd());
    ASSERT_FALSE(state->isInited());
    ASSERT_FALSE(state->isConnected());
    ASSERT_FALSE(state->isLogined());
    ASSERT_FALSE(state->isDisconnected());

    ASSERT_EQ(0, state->toInited());
    ASSERT_EQ(0, state->toConnected());
    ASSERT_EQ(0, state->toLogined());
    ASSERT_EQ(0, state->toDisconnected());
    ASSERT_EQ(0, state->toEnd());

    state->log(std::cout);
    delete state;
}

#include "BreakPointStateSST.h"

TEST(BreakPointStateSSTTest, use){
    IBreakPointState * state = new BreakPointStateSST;
    ASSERT_TRUE(state->isEnd());
    ASSERT_FALSE(state->isInited());
    ASSERT_FALSE(state->isConnected());
    ASSERT_FALSE(state->isLogined());
    ASSERT_FALSE(state->isDisconnected());

    ASSERT_EQ(0, state->toInited());
    ASSERT_EQ(0, state->toConnected());
    ASSERT_EQ(0, state->toLogined());
    ASSERT_EQ(0, state->toDisconnected());
    ASSERT_EQ(0, state->toEnd());

    state->log(std::cout);
    delete state;
}


#include <functional>

int f1(int arg){
    return arg;
}


class Object {
public:
    int memfn(int arg){
        return arg;
    }
};

TEST(FuntionTest, use){
    {
        std::function<int (int)> callback = f1;
        ASSERT_TRUE(callback != nullptr);
        ASSERT_EQ(10, callback(10));
    }

    {
        Object o;
        std::function<int (int)> callback = std::bind(&Object::memfn, o, std::placeholders::_1);
        ASSERT_TRUE(callback != nullptr);
        ASSERT_EQ(10, callback(10));
    }

    std::function<int (int)> callback;
    {
        ASSERT_TRUE(callback == nullptr);
    }
}
